﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ResourceEditor.Core.Search;
using System.Linq.Expressions;

namespace ResourceEditor.Core.ResourceDataObjects
{
    public class ResourceDataString : ResourceData<string>, ISupportSearch
    {
        #region Ctor
        public ResourceDataString(ResourceFile container)
            : base(container)
        {

        }
        #endregion

        #region ISupportSearch Members

        public SearchResults Search(SearchStructure structure)
        {
            Func<List<int>> function = GetFunction(structure);
            List<int> indexes = function.Invoke();

            if (indexes.Count == 0)
            {
                return null;
            }

            indexes = SubtractDeletedRow(indexes);
            
            return new SearchResults(structure.Clone(), indexes.ToArray());
        }

        
        #endregion

        #region Methods
        private List<int> SubtractDeletedRow(List<int> indexes)
        {
            List<int> deletedIndexes = Items.FindAllIndex(item => item.State == ItemState.Deleted);

            for (int i = 0; i < indexes.Count; i++)
            {
                indexes[i] -= deletedIndexes.Count(item => item < indexes[i]);
            }

            return indexes;
        }

        private Func<List<int>> GetFunction(SearchStructure structure)
        {
            if (structure.Contain)
            {
                if (structure.Keys && structure.Values)
                {
                    return () => Items.FindAllIndex(data =>
                        (data.Key.ToLower().Contains(structure.FindWhat.ToLower()) ||
                        data.Current.ToLower().Contains(structure.FindWhat.ToLower())) 
                        && data.State != ItemState.Deleted);
                }
                else if (structure.Keys)
                {
                    return () => Items.FindAllIndex(data => data.Key.ToLower().Contains(structure.FindWhat.ToLower()) && data.State != ItemState.Deleted);
                }
                else if (structure.Values)
                {
                    return () => Items.FindAllIndex(data => data.Current.ToLower().Contains(structure.FindWhat.ToLower()) && data.State != ItemState.Deleted);
                }
            }
            else
            {
                if (structure.Keys && structure.Values)
                {
                    return () => Items.FindAllIndex(data =>
                        (data.Key.ToLower() == structure.FindWhat.ToLower() ||
                        data.Current.ToLower() == structure.FindWhat.ToLower()) && 
                        data.State != ItemState.Deleted);
                }
                else if (structure.Keys)
                {
                    return () => Items.FindAllIndex(data => data.Key.ToLower() == structure.FindWhat.ToLower() && data.State != ItemState.Deleted);
                }
                else if (structure.Values)
                {
                    return () => Items.FindAllIndex(data => data.Current.ToLower() == structure.FindWhat.ToLower() && data.State != ItemState.Deleted);
                }
            }

            return null;
        }
        #endregion
    }
}
